#include "./src/core/geometry.h"
#include "./src/core/pbrt.h"
#include "./src/core/api.h"

using namespace Pbrt;

static void usage(const char* msg = nullptr)
{
    if(msg)
        std::cerr << msg << "\n";
    else
        std::cerr << R"(usage: pbrt [<options>] <filename.pbrt...>
        Rendering options:
        --cropwindow <x0,x1,y0,y1> Specify an image crop window.
        --help               Print this help text.
        --nthreads <num>     Use specified number of threads for rendering.
        --outfile <filename> Write the final image to the given filename.
        --quick              Automatically reduce a number of quality settings to
                            render more quickly.
        --quiet              Suppress all text output other than error messages.

        Logging options:
        --logdir <dir>       Specify directory that log files should be written to.
                            Default: system temp directory (e.g. $TMPDIR or /tmp).
        --logtostderr        Print all logging messages to stderr.
        --minloglevel <num>  Log messages at or above this level (0 -> INFO,
                            1 -> WARNING, 2 -> ERROR, 3-> FATAL). Default: 0.
        --v <verbosity>      Set VLOG verbosity.

        Reformatting options:
        --cat                Print a reformatted version of the input file(s) to
                            standard output. Does not render an image.
        --toply              Print a reformatted version of the input file(s) to
                            standard output and convert all triangle meshes to
                            PLY files. Does not render an image.
        )" << "\n";                    
}

int main(int argc, char* argv[]) 
{
    FLAGS_log_dir = "/home/sdai/data/lhj/pbrt_rebuild/log";
    FLAGS_stderrthreshold = 1;
    google::InitGoogleLogging(argv[0]);
    LOG(INFO) << "The project author is hamster";

    Options options;
    std::vector<std::string> filenames;
    for(int i = 1; i < argc; ++i)
    {
        if(!strcmp(argv[i], "--nthreads") || !strcmp(argv[i], "-nthreads"))
        {
            if(i + 1 == argc)
                usage("missing value after --nthreads argument");
            options.nThreads = atoi(argv[++i]);
        }
        else if (!strncmp(argv[i], "--nthreads=", 11))
        {
            options.nThreads = atoi(&argv[i][11]);
        }
        else if(!strcmp(argv[i], "--outfile") || !strcmp(argv[i], "-outfile"))
        {
            if(i + 1 == argc)
                usage("missing value after --outfile argument");
            options.imageFile = argv[++i];
        }
        else if(!strncmp(argv[i], "--outfile=", 10))
        {
            options.imageFile = &argv[i][10];
        }
        else if (!strcmp(argv[i], "--cropwindow") || ! strcmp(argv[i], "-cropwindow"))
        {
            if(i + 4 >= argc)
                usage("missing value after --cropwindow argument");
            options.cropWindow[0][0] = atof(argv[++i]);
            options.cropWindow[0][1] = atof(argv[++i]);
            options.cropWindow[1][0] = atof(argv[++i]);
            options.cropWindow[1][1] = atof(argv[++i]);
        }
        else if(!strcmp(argv[i], "--logdir") || !strcmp(argv[i], "-logdir"))
        {
            if(i + 1 == argc)
                usage("missing value after --logdir argument");
            FLAGS_log_dir = argv[++i];
        }
        else if(!strncmp(argv[i], "--logdir=", 9))
        {
            FLAGS_log_dir = &argv[i][9];
        }
        else if(!strcmp(argv[i], "--minloglevel") || !strcmp(argv[i], "-minloglevel"))
        {
            if(i + 1 == argc)
                usage("missing value after --minloglevel argument");
            FLAGS_minloglevel = atoi(argv[++i]);
        }
        else if(!strncmp(argv[i], "--minloglevel=", 14))
        {
            FLAGS_minloglevel = atoi(&argv[i][14]);
        }
        else if(!strcmp(argv[i], "--quick") || !strcmp(argv[i], "-quick"))
        {
            options.quickRender = true;
        }
        else if(!strcmp(argv[i], "--quiet") || !strcmp(argv[i], "-quiet"))
        {
            options.quiet = true;
        }
        else if(!strcmp(argv[i], "--cat") || !strcmp(argv[i], "-cat"))
        {
            options.cat = true;
        }
        else if(!strcmp(argv[i], "--toply") || !strcmp(argv[i], "-toply"))
        {
            options.toPly = true;
        }
        else if(!strcmp(argv[i], "--v") || !strcmp(argv[i], "-v"))
        {
            if(i + 1 == argc)
                usage("missing value after -v argument");
            FLAGS_v = atoi(argv[++i]);
        }
        else if(!strncmp(argv[i], "--v=", 4))
        {
            FLAGS_v = atoi(&argv[i][4]);
        }
        else if(!strcmp(argv[i], "--logtostderr"))
        {
            FLAGS_logtostderr = true;
        }
        else if(!strcmp(argv[i], "--help") || !strcmp(argv[i], "-help") || !strcmp(argv[i], "-h"))
        {
            usage();
            return 0;
        }
        else
        {
            filenames.push_back(argv[i]);
        }
    }
    #ifdef NDEBUG
    LOG(INFO) << "Running debug build";
    printf("*** Running debug build ***\n");
    #endif

    // Warning("this is a warning %d %d %d %d", 10, 10, 10, 10);
    // Warning(std::string("this is a warning 2 %d %d %d %d"), 10, 10, 10, 10);
    
    pbrtInit(options);
    Vector2 a = Vector2(1.13134, 2.222344);
    Vector3 b = Vector3(1.13134, 2.222344, 3.333344); 
    std::cout << a << std::endl;
    std::cout << b << std::endl;
    auto c = Bounds3<int>(Point3<int>(1, 2, 3), Point3<int>(4, 5, 6));


    Bounds2 c(Point2f(2.0f, 3.0f), Point2f(4.0f, 5.0f));
    std::cout << c << std::endl;

    return 0;

    return 0;
}